<?php

namespace app\index\service;

use app\common\model\AccountTokenActivity;
use app\common\model\AccountTokenGift;
use app\common\model\RankBroadcast;
use app\common\service\TransfersServer;
use app\index\dao\AccountTokenGiftDao;
use app\index\model\UM as UM;
use ShidianUtil\Concurrent\Synchronizer;
use think\exception\ValidateException;

/**
 * Class CoinGiftService
 * @package app\index\service
 */
class CoinGiftService
{
    // 赠送的通信币数量
    private float $coin = 70;

    // dao
    private AccountTokenGiftDao $accountTokenGiftDao;
    private BroadcastService $broadcastService;

    public function __construct(AccountTokenGiftDao $accountTokenGiftDao, BroadcastService $broadcastService)
    {
        $this->accountTokenGiftDao = $accountTokenGiftDao;
        $this->broadcastService = $broadcastService;
    }

    /**
     * 新增
     * @param UM $user
     * @param array $params
     * @return  AccountTokenGift
     */
    public function add(UM $user, array $params): ?AccountTokenGift
    {
        $memberId = $user->id;
        $memberName = $user->showName;
        $accountTokenActivityId = $params['accountTokenActivityId'] ?? null;

        if (!is_id($accountTokenActivityId)) {
            throw new ValidateException('请选择一个活动');
        }

        // 查询是否赠送过
        $record = $this->findRecord($accountTokenActivityId, $memberId);

        if ($record) {
            throw new ValidateException('您已经领取过了');
        }

        $accountTokenActivity = AccountTokenActivity::where('id', $accountTokenActivityId)->find();
        if (is_null($accountTokenActivity)) {
            throw new ValidateException('该活动不存在或已经结束');
        }

        $result = $this->give($accountTokenActivity, $memberId);

        $this->addBroadcast($memberId, $memberName, $result ? $result->coin : '');

        return $result;
    }

    private function give(AccountTokenActivity $accountTokenActivity, $memberId): ?AccountTokenGift
    {
        $accountTokenActivityId = $accountTokenActivity->id;
        $coin = $accountTokenActivity->coin;
        $accountTokenActivityName = $accountTokenActivity->name;

        if ($coin < 0.01) {
            return null;
        }

        $success = false;
        $record = null;

        $signature = __CLASS__ . $memberId;
        $this->getSynchronizer()->synchronized($signature, function () use (&$success, &$record, $accountTokenActivityId, $memberId, $coin) {

            // 查询是否赠送过
            $record = $this->findRecord($accountTokenActivityId, $memberId);
            if ($record) {
                return;
            }

            // 插入赠送记录
            $params = [
                'accountTokenActivityId' => $accountTokenActivityId,
                'memberId' => $memberId,
                'coin' => $coin,
            ];

            $record = $this->accountTokenGiftDao->insertActive($params, []);

            $success = true;
        });

        if (!$success) {
            throw new ValidateException('您已经领取过了');
        }

        $describe = $accountTokenActivityName . ' ' . ((float)$coin) . '个';

        $this->createTransfer($memberId, $coin, $describe, $accountTokenActivityId, $record->id);

        return $record;
    }

    private function findRecord($accountTokenActivityId, $memberId): ?AccountTokenGift
    {
        return AccountTokenGift::where('memberId', $memberId)
            ->where('accountTokenActivityId', $accountTokenActivityId)
            ->find();
    }

    /**
     * 创建转账申请
     * @param $memberId
     * @param $coin
     * @param $describe
     * @param $accountTokenActivityId
     * @param $accountTokenGiftId
     * @return void
     */
    private function createTransfer($memberId, $coin, $describe, $accountTokenActivityId, $accountTokenGiftId)
    {
        $transferType = TRANSFER_COIN_GIFT;
        $payMethod = PAYMENT_COIN;
        $accountNumber = $memberId;
        $totalMoney = $coin;
        $append = [
            'accountTokenActivityId' => $accountTokenActivityId,
            'accountTokenGiftId' => $accountTokenGiftId,
        ];
        $this->getTransfersServer()->pushTransferToMember($transferType, $memberId, $payMethod, $accountNumber, $totalMoney, $describe, $append);
    }

    private function addBroadcast($lawyerId, $lawyerName, $num): void
    {
        $message = [
            ['type' => 'text', 'red' => 102, 'text' => '获得了完成身份认证奖励 '],
            ['type' => 'text', 'red' => 101, 'text' => $num],
            ['type' => 'text', 'red' => 102, 'text' => ' 通信币'],
        ];

        $this->broadcastService->addBroadcast(RankBroadcast::DONGTAI, $lawyerId, $lawyerName, $message);
    }

    private function getTransfersServer(): TransfersServer
    {
        return app(TransfersServer::class);
    }

    private function getSynchronizer(): Synchronizer
    {
        return app(Synchronizer::class);
    }
}
